package ICM_OCSF;

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.Scanner;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.locks.Lock;

import Boundry.ReconnectPanel;
import Controllers.GlobalData;
import Entity.Message;

import ocsf.client.AbstractClient;

/*		Class : Client
 * 		all of the implemntation needed for clinet side connection
 * 
 * 		Author : Shimon,Guy
 */


/*   
 * the steps to send message to client
 * 
 *  Client.sendToServer(Message)
 * 	while (true){
 * 	if (Client.isRecivedMessage()==true){
 * 		answermessage = getAnsweredMessage(Message);
 *  if (answermessage!=null)
 *  	break;
 *  }
 *  }
 * 
 * 
 */



public class Client extends AbstractClient 
{
	private ArrayList<Message> msgQueue;
	
	private String ip=null,port=null;
	
	public Client(String host, int port)   
	{
		super(host, port);
		// TODO Auto-generated constructor stub
	}
	
	
	@Override
	/*
	 * (non-Javadoc)
	 * @see ocsf.client.AbstractClient#handleMessageFromServer(java.lang.Object)
	 */
	protected void handleMessageFromServer(Object msg)
	{
		// TODO Auto-generated method stub
		
		if(msg != null)
		{
			if (msg instanceof Message){
				
				synchronized(msgQueue)
				{
					System.out.println("handle message"+msg.toString());
					msgQueue.add((Message)msg);
					System.out.println(isRecivedMessage());
					System.out.println("insert new msg . size off the queqe is " +msgQueue.size()  );
				}
			}
				
		}

	}

	@Override
	/*
	 * (non-Javadoc)
	 * @see ocsf.client.AbstractClient#connectionEstablished()
	 */
	protected void connectionEstablished() 
	{
		// TODO Auto-generated method stub
	  msgQueue = new ArrayList<Message>();
		
	}

	@Override
	/*
	 * (non-Javadoc)
	 * @see ocsf.client.AbstractClient#connectionClosed()
	 */
	protected void connectionClosed() {
		// TODO Auto-generated method stub
		synchronized(msgQueue)
		{
			msgQueue.clear();
			msgQueue = null;
		}
	}
	/**
	 * this method endicates whatever if there is message wating in queue
	 * @return true or false according to if there is a message in message quese
	 */
	public boolean isRecivedMessage(){
		//System.out.println(msgQueue.size());
		
		synchronized(msgQueue)
		{
			if (msgQueue.size()==0)
				return false;
			else
				return true;
		}
	}
	/**
	 * this method gets the message from the queue if and only if the message matched the returned message form the
	 * server 
	 * @param msg
	 * @return message
	 */
	public Message getAnsweredMessage(Message msg)
	{
		//System.out.println("entry point get answered");
		if (msg==null)
			return null;
		else if (isRecivedMessage()==false)
			return null;
		//System.out.println("entry point get answered con");
		synchronized(msgQueue)
		{
			//Message[] Msgs =  (Message[]) msgQueue.toArray();
			for (Message msgCurrent : msgQueue){
				
				//System.out.println(msgCurrent.toString());
				System.out.println(msgCurrent.toString()+" ------"+ msg.toString());
				if (isMathedAnswerMessage(msg, msgCurrent))
				{
					System.out.println("getansswered "+msgCurrent.toString());
					msgQueue.remove(msgCurrent);
					return (Message) msgCurrent;
				}
			}
		}
		//System.out.println("finish point get answered");
		return null;
	}

	
	
	/**
	 * @param Sentmsg
	 * @param RecivedMessage
	 * @return
	 */
	private boolean isMathedAnswerMessage(Message msg,
			Message msgcurr) {
		//System.out.println(((RecivedMessage.getOpCode()+1000)==Sentmsg.getOpCode()) && (RecivedMessage.getMessageID()==Sentmsg.getMessageID()));
		return (((msgcurr.getOpCode())==msg.getOpCode()+1000) && (msgcurr.getMessageID()==msg.getMessageID()));
	}
	/*
	 * (non-Javadoc)
	 * @see ocsf.client.AbstractClient#connectionException(java.lang.Exception)
	 */
	 protected void connectionException(Exception exception) 
	 {
		 System.out.println("Connection Lost");
		 GlobalData.guiMangaer.switchScreen(new ReconnectPanel());
	 }
	


}
	
	
	

